home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Suzy B Software 2
/
Suzy B Software CD-ROM 2 (1994).iso
/
extras
/
programm
/
gemfsc20
/
gemfsc20.lzh
/
GEMFUNCS
/
OBJNSLID.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-20
|
11KB
|
398 lines
/**************************************************************************
*
*************************************************************************/
#include "gemfintl.h"
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
static OBJECT nslider_objects[] = {
{ -1, 1, 4, G_IBOX, NONE, NORMAL, (_Ob_spec_t)0x00001181L, 0x0000, 0x0000, 0x0000, 0x0000},
{ 2, -1, -1, G_BOXCHAR, NONE, NORMAL, (_Ob_spec_t)0x04FF1181L, 0x0000, 0x0000, 0x0000, 0x0000},
{ 4, 3, 3, G_BOX, NONE, NORMAL, (_Ob_spec_t)0x00FF1191L, 0x0000, 0x0000, 0x0000, 0x0000},
{ 2, -1, -1, G_BUTTON, NONE, NORMAL, (_Ob_spec_t)NULL, 0x0000, 0x0000, 0x0000, 0x0000},
{ 0, -1, -1, G_BOXCHAR, LASTOB, NORMAL, (_Ob_spec_t)0x03FF1181L, 0x0000, 0x0000, 0x0000, 0x0000},
};
#define NSLIDE_ROOT 0
#define NSLIDE_DOWNARROW 1
#define NSLIDE_PAGE 2
#define NSLIDE_SLIDER 3
#define NSLIDE_UPARROW 4
#define NSLIDE_ARROW_WIDTH (gl_wbox)
#define MIN_NSLIDE_OBJECT_WIDTH (4*NSLIDE_ARROW_WIDTH)
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
typedef struct nslide_info {
XUSERBLK xub; /* standard XUSERDEF header */
short statusobj; /* obj in main tree that shows cur selection */
long min; /* minimum numeric value slider can have */
long max; /* maximum numeric value slider can have */
short wpage; /* width of pager bar in pixels */
short wslider; /* width of slider box in pixels */
OBJECT dialog[5]; /* rectangles describing slider */
} NSLIDEINFO;
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
#ifdef GEMFAST_PROTOS
typedef void GCALLBACK (EVNREPEATFUNC)(void *udata, short mx, short my);
INTERNAL_VFUNC clip_slider_value(NSLIDEINFO *pinfo);
INTERNAL_VFUNC render_nslide(NSLIDEINFO *pinfo, short startobj, GRECT *cliprect);
static long GCALLBACK see_nslide(XPARMBLK *pb);
static void GCALLBACK inc_slider(void *udata, short mx, short my);
static void GCALLBACK dec_slider(void *udata, short mx, short my);
static void repeat_on_button_down(EVNREPEATFUNC *pfunc, void *udata);
static void GCALLBACK udslider(OBJECT *ptree, short obj, short slidepos, void *udata);
static XUBT_STATUS GCALLBACK feel_nslide(XUSERBLK *xub, short mx, short my, short clicks);
#else
typedef void GCALLBACK (EVNREPEATFUNC)();
#endif
INTERNAL_VFUNC clip_slider_value(pinfo)
NSLIDEINFO *pinfo;
/*****************************************************************************
*
****************************************************************************/
{
long value = (long)pinfo->xub.ob_spec;
if (value < pinfo->min) {
value = pinfo->min;
} else if (value > pinfo->max) {
value = pinfo->max;
}
pinfo->xub.ob_spec = (_Ob_spec_t)value;
}
INTERNAL_VFUNC render_nslide(pinfo, startobj, cliprect)
NSLIDEINFO *pinfo;
short startobj;
GRECT *cliprect;
/*****************************************************************************
*
****************************************************************************/
{
long value;
long vrange;
short prange;
short nchars;
char buf[20];
OBJECT *dialog = pinfo->dialog;
clip_slider_value(pinfo);
nchars = sprintf(buf, "%ld", pinfo->xub.ob_spec);
dialog[NSLIDE_SLIDER].ob_width = (nchars+1) * gl_wchar;
dialog[NSLIDE_SLIDER].ob_spec = (_Ob_spec_t)buf;
value = (long)pinfo->xub.ob_spec - pinfo->min;
vrange = pinfo->max - pinfo->min;
prange = dialog[NSLIDE_PAGE].ob_width - dialog[NSLIDE_SLIDER].ob_width;
dialog[NSLIDE_SLIDER].ob_x =
(short)((((value*1000L)/vrange)*(prange))/1000L);
obj__draw(dialog, startobj, MAX_DEPTH, cliprect);
}
static long GCALLBACK see_nslide(pb)
XPARMBLK *pb;
/*****************************************************************************
*
****************************************************************************/
{
NSLIDEINFO *pinfo = (NSLIDEINFO *)pb->pub;
pinfo->dialog[ROOT].ob_x = pb->drawrect.g_x;
pinfo->dialog[ROOT].ob_y = pb->drawrect.g_y;
render_nslide(pinfo, ROOT, &pb->cliprect);
return 0;
}
static void GCALLBACK inc_slider(udata, mx, my)
void *udata;
short mx;
short my;
/*****************************************************************************
*
****************************************************************************/
{
NSLIDEINFO *pinfo = udata;
pinfo->xub.ob_spec = (_Ob_spec_t)((long)pinfo->xub.ob_spec + 1);
render_nslide(pinfo, NSLIDE_PAGE, &gl_rwdesk);
}
static void GCALLBACK dec_slider(udata, mx, my)
void *udata;
short mx;
short my;
/*****************************************************************************
*
****************************************************************************/
{
NSLIDEINFO *pinfo = udata;
pinfo->xub.ob_spec = (_Ob_spec_t)((long)pinfo->xub.ob_spec - 1);
render_nslide(pinfo, NSLIDE_PAGE, &gl_rwdesk);
}
static void repeat_on_button_down(pfunc, udata)
EVNREPEATFUNC *pfunc;
void *udata;
/*****************************************************************************
*
****************************************************************************/
{
short mx, my, mb, dmy;
short first_time = TRUE;
do {
graf_mkstate(&mx, &my, &mb, &dmy);
if (mb || first_time) {
(*pfunc)(udata, mx, my);
}
first_time = 0;
evnx_timer(50L);
} while (mb);
}
static void GCALLBACK udslider(ptree, obj, slidepos, udata)
OBJECT *ptree;
short obj;
short slidepos;
void *udata;
/*****************************************************************************
*
****************************************************************************/
{
NSLIDEINFO *pinfo = udata;
long value;
long vrange;
if (slidepos > 2000) {
slidepos -= 2000;
} else if (slidepos > 1000) {
slidepos -= 1000;
}
vrange = pinfo->max - pinfo->min;
value = (vrange * (slidepos-1)) / 1000L;
pinfo->xub.ob_spec = (_Ob_spec_t)(value + pinfo->min);
render_nslide(pinfo, NSLIDE_PAGE, &gl_rwdesk);
}
static XUBT_STATUS GCALLBACK feel_nslide(xub, mx, my, clicks)
XUSERBLK *xub;
short mx;
short my;
short clicks;
/*****************************************************************************
* routine to handle a click on a slider object.
****************************************************************************/
{
NSLIDEINFO *pinfo = (NSLIDEINFO *)xub;
short clickobj;
XUBT_STATUS rv = XUBT_VALUE;
clickobj = objc_find(pinfo->dialog, ROOT, MAX_DEPTH, mx, my);
switch (clickobj) {
case NSLIDE_PAGE:
case NSLIDE_SLIDER:
grf_udslidebox(pinfo->dialog, NSLIDE_SLIDER, FALSE, udslider, pinfo);
break;
case NSLIDE_DOWNARROW:
repeat_on_button_down(dec_slider, pinfo);
break;
case NSLIDE_UPARROW:
repeat_on_button_down(inc_slider, pinfo);
break;
default:
rv = XUBT_NONE;
break;
}
return rv;
}
short obj_make_nslide(ptree, obj, statusobj, min, max)
OBJECT *ptree;
short obj;
short statusobj;
long min;
long max;
/*****************************************************************************
*
****************************************************************************/
{
register OBJECT *pobj = &ptree[obj];
register NSLIDEINFO *pinfo;
/*------------------------------------------------------------------------
* validate parms.
*----------------------------------------------------------------------*/
if (0 == apl_vshared()) {
return gfErr_vdi_handle;
}
if (pobj->ob_width < MIN_NSLIDE_OBJECT_WIDTH) {
return gfErr_object_too_small;
}
if (max <= min) {
return gfErr_parameter_range;
}
/*------------------------------------------------------------------------
* If the object has already been made into a G_NSLIDE extended object,
* just get its pointer, else make it into such an object.
*----------------------------------------------------------------------*/
if ((pobj->ob_type & 0x00FF) == G_USERDEF) {
pinfo = (NSLIDEINFO *)pobj->_Ob_spec;
if (pinfo->xub.ob_type != G_NSLIDE) {
return gfErr_wrong_type;
}
} else {
if (NULL == (pinfo = apl_malloc((long)sizeof(*pinfo)))) {
return gfErr_no_memory;
}
obj_mxuserdef(ptree, obj, &pinfo->xub, see_nslide, feel_nslide, (long)sizeof(*pinfo));
pinfo->xub.ob_type = G_NSLIDE;
pinfo->xub.ob_spec = 0;
}
pinfo->min = min;
pinfo->max = max;
pinfo->wpage = pobj->ob_width - (2 * NSLIDE_ARROW_WIDTH);
pinfo->wslider = NSLIDE_ARROW_WIDTH;
pinfo->statusobj = statusobj;
if (statusobj != NO_OBJECT) {
rsc_sstrings(ptree, statusobj, "", -1);
}
/*------------------------------------------------------------------------
* build the rectangles describing the on-screen nslide.
*----------------------------------------------------------------------*/
memcpy(pinfo->dialog, nslider_objects, sizeof(nslider_objects));
#define SetRect(idx, x, y, w, h)\
pinfo->dialog[(idx)].ob_x = (x);\
pinfo->dialog[(idx)].ob_y = (y);\
pinfo->dialog[(idx)].ob_width = (w);\
pinfo->dialog[(idx)].ob_height = (h)
SetRect(ROOT,
pobj->ob_x,
pobj->ob_y,
pobj->ob_width,
pobj->ob_height);
SetRect(NSLIDE_DOWNARROW,
0,
0,
NSLIDE_ARROW_WIDTH,
pobj->ob_height);
SetRect(NSLIDE_PAGE,
NSLIDE_ARROW_WIDTH,
0,
pinfo->wpage - 1,
pobj->ob_height);
SetRect(NSLIDE_SLIDER,
0,
0,
pinfo->wslider,
pobj->ob_height);
SetRect(NSLIDE_UPARROW,
NSLIDE_ARROW_WIDTH + pinfo->wpage,
0,
NSLIDE_ARROW_WIDTH,
pobj->ob_height);
#undef SetRect
return 0;
}
long obj_get_nslide(ptree, obj)
OBJECT *ptree;
short obj;
/*****************************************************************************
*
****************************************************************************/
{
return obj_gvalue(ptree, obj);
}
void obj_set_nslide(ptree, obj, newvalue)
OBJECT *ptree;
short obj;
long newvalue;
/*****************************************************************************
*
****************************************************************************/
{
NSLIDEINFO *pinfo;
if (ptree[obj].ob_flags & INDIRECT) {
pinfo = *(NSLIDEINFO **)ptree[obj].ob_spec;
} else {
pinfo = (NSLIDEINFO *)ptree[obj].ob_spec;
}
pinfo->xub.ob_spec = (_Ob_spec_t)newvalue;
clip_slider_value(pinfo);
}
void obj_change_nslide(ptree, obj, newmin, newmax)
OBJECT *ptree;
short obj;
long newmin;
long newmax;
/*****************************************************************************
*
****************************************************************************/
{
NSLIDEINFO *pinfo;
if (ptree[obj].ob_flags & INDIRECT) {
pinfo = *(NSLIDEINFO **)ptree[obj].ob_spec;
} else {
pinfo = (NSLIDEINFO *)ptree[obj].ob_spec;
}
pinfo->min = newmin;
pinfo->max = newmax;
clip_slider_value(pinfo);
}